package junk;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import processing.core.*;
import jsc.distributions.Hypergeometric;

public class Popups extends Main1 {
	private static final long serialVersionUID = 1L;
	
	public void newAnnotationPopup(PApplet p)
	{
		p.scale(p.width/WIDTH1,p.height/HEIGHT1);
		float innerRadius1;
		innerRadius1 = (HEIGHT1/p.height)*innerRadius; 
		p.fill(255,255,255,200);
		p.noStroke();
		p.rectMode(Main1.CORNER);
		((Main1) p).roundRect(-innerRadius1 + 150,-innerRadius1 + 150, innerRadius1*2 - 300, innerRadius1*2 - 300);
		p.textFont(font32);
		p.textAlign(Main1.CENTER);
		p.fill(48,165,252);
		p.text("New Ring Annotation for " + newAnnotationGroup.name + "?", 0,  -innerRadius1 + 185);
		float[] dataValues = new float[firstAnnotation.genes.length];
		int columnInData = newAnnotationGroup.columnInData;
		int dataset = -1;		
		for( int z = 0; z< ReadGenes.datasets.length; z++)
		{
			if(newAnnotationGroup.annotation.equals(ReadGenes.datasets[z]))
				dataset = z;
			else if(newAnnotationGroup.set.equals(ReadGenes.datasets[z]))
				dataset = z;
		}	
		for(int i = 0; i< dataValues.length; i++)
		{
			if(newAnnotationGroup.type.equals("Raw"))
			{
				if(percentValues)
					dataValues[i] = firstAnnotation.genes[i].percentExpressionConditions.get(dataset)[columnInData];
				else
					dataValues[i] = firstAnnotation.genes[i].expressionConditions.get(dataset)[columnInData];
			}
			else if(newAnnotationGroup.type.equals("P-Value"))
				dataValues[i] = (float) Math.log10(firstAnnotation.genes[i].expressionConditions.get(dataset)[columnInData]);
			else if(newAnnotationGroup.type.equals("Boolean"))
			{
				BooleanGroup b = (BooleanGroup) newAnnotationGroup;
				dataValues[i] = (float) b.percentExpression( i);
				percentValues = true;
				dataset = -2;
			}
		}
		Arrays.sort(dataValues);
		float min = dataValues[(int)((dataValues.length-1)*.01)];
		float max = dataValues[(int)((dataValues.length-1)*.99)];
		int numBins = 100;
		float interval = (max-min)/(float)(numBins-1);
		int[] counts = new int[numBins];
		float currentCutoff = min;
		int currentBin = 0;
		for(int i = 0; i< dataValues.length; i++)
		{			
			while(dataValues[i] > currentCutoff  && currentBin < (numBins - 1))
			{
				currentCutoff += interval;
				currentBin++;
			}
			counts[currentBin] ++;
		}
		
		int[] countsCopy = new int[numBins];
		for(int i= 0; i< numBins; i++)
			countsCopy[i] = counts[i];
		Arrays.sort(countsCopy);
		int maxCount = countsCopy[numBins - 1];
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 2];
		if( maxCount == counts[0] || maxCount == counts[numBins-1])
			maxCount= countsCopy[numBins - 3];		
		
		boolean[] flags = new boolean[numBins];
		for(int i = 0; i< numBins; i++)
			flags[i] = false;
		
		if(Backend.removeZeros)
		{
			maxCount = countsCopy[numBins - 2];
			for(int i= 0; i< numBins; i++)
				if(counts[i] > maxCount)
				{
					counts[i]= maxCount;
					flags[i] =true;					
				}
		}
		

		p.stroke(0,0,255);
		p.line(-innerRadius1 + 200, 0, innerRadius1 - 200, 0);
		p.noFill();
		p.beginShape();
		for(int i = 1; i<numBins-1; i++)
		{
			float x = -innerRadius1 + 200f + (((float)i/(float)numBins)*(innerRadius1*2f - 400f));
			float y = (-innerRadius1 + 250f)*((float)counts[i]/(float)maxCount);
			p.vertex(x,y);
			if(flags[i]) 
			{
				p.stroke(255,0,0);
				p.ellipse(x,y,3,3);
				p.stroke(0,0,255);
			}
		}
		p.endShape();
		p.stroke(255,0,0,200);
		names= new String[groupCutoff.length+1];
		int[] geneCounts= new int[groupCutoff.length+1];
		NumberFormat formatter = new DecimalFormat();
		if(percentValues) formatter = new DecimalFormat("0.##");
		else formatter = new DecimalFormat("0.##E0");
		for(int i = 0; i< groupCutoff.length; i++)
		{
			p.textAlign(Main1.LEFT);
			p.textFont(font10);
			p.fill(255,0,0);
			p.line((-innerRadius1 + 200) + ((float)groupCutoff[i]/numBins)*((innerRadius1*2f - 400f)), 5, (-innerRadius1 + 200) + ((float)groupCutoff[i]/numBins)*((innerRadius1*2f - 400f)), (-innerRadius1 + 250f));
			if(newAnnotationGroup.type.equals("P-Value")) p.text(formatter.format(Math.pow(10,interval*((float)groupCutoff[i]) + min)),(-innerRadius1 + 200) + ((float)groupCutoff[i]/numBins)*((innerRadius1*2f - 400f)), 18);
			else p.text(formatter.format(interval*((float)groupCutoff[i]) + min),(-innerRadius1 + 200) + ((float)groupCutoff[i]/numBins)*((innerRadius1*2f - 400f)), 18);
			p.textFont(font32);
			p.fill(255,0,0,128);
			float spot;
			if(i>0)	spot = (float)(groupCutoff[i]+groupCutoff[i-1])/(numBins*2f);
			else spot = 0;
			p.text(i+1 ,(-innerRadius1 + 200) + spot*((innerRadius1*2f - 400f)), -125);
			p.textFont(font14);
			p.fill(0);
			if(groupCutoffRaw == null) groupCutoffRaw = new float[groupCutoff.length];
			if(i==0) 
			{
				if(newAnnotationGroup.type.equals("P-Value"))
				{
					groupCutoffRaw[0] = (float) Math.pow(10,interval*((float)groupCutoff[i]) + min);
					names[i] = "Group "+ (i+1) + ": \tp < " + formatter.format(groupCutoffRaw[0]);
				}
				else 
				{
					groupCutoffRaw[0] = interval*((float)groupCutoff[i]) + min;
					names[i] = "Group "+ (i+1) + ": \tExp < " + formatter.format(groupCutoffRaw[0]);
				}
				geneCounts[i] = 0;
				for(int j = 0; j<groupCutoff[i]; j++)
					geneCounts[i] += counts[j];
			}
			else 
			{
				if(newAnnotationGroup.type.equals("P-Value"))
				{
					groupCutoffRaw[i] = (float) Math.pow(10,interval*((float)groupCutoff[i]) + min);
					names[i] = "Group "+ (i+1) + ": \t"+ formatter.format(interval*((float)groupCutoff[i-1]) + min) + "< p < " + formatter.format(groupCutoffRaw[i]);
				}
				else 
				{
					groupCutoffRaw[i] = interval*((float)groupCutoff[i]) + min;
					names[i] = "Group "+ (i+1) + ": \t"+ formatter.format(interval*((float)groupCutoff[i-1]) + min) + "< Exp < " + formatter.format(groupCutoffRaw[i]);
				}
				geneCounts[i] = 0;
				for(int j = groupCutoff[i-1]; j<groupCutoff[i]; j++)
					geneCounts[i] += counts[j];
			}
			p.text(names[i], -innerRadius1+200, i*30 + 50);
			p.text(geneCounts[i] + " genes in group", -innerRadius1+600, i*30 + 50);
		}
		p.textFont(font32);
		p.fill(255,0,0,128);
		p.text((groupCutoff.length+1), innerRadius1 - 200, -125);
		p.textFont(font14);
		p.fill(0);
		if(newAnnotationGroup.type.equals("P-Value"))
			names[groupCutoff.length] = "Group "+ (groupCutoff.length+1) + ": \tp > " + formatter.format(interval*((float)groupCutoff[groupCutoff.length-1]) + min);
		else
			names[groupCutoff.length] = "Group "+ (groupCutoff.length+1) + ": \tExp > " + formatter.format(interval*((float)groupCutoff[groupCutoff.length-1]) + min);

		geneCounts[groupCutoff.length] = 0;
		for(int j = groupCutoff[groupCutoff.length-1]; j<counts.length; j++)
			geneCounts[groupCutoff.length] += counts[j];
		p.text(names[groupCutoff.length], -innerRadius1+200, groupCutoff.length*30 + 50);
		p.text(geneCounts[groupCutoff.length] + " genes in group", -innerRadius1+600, groupCutoff.length*30 + 50);
		p.noStroke();
		p.textAlign(CENTER);
		int color = p.color(255,0,0,200);
		if(Main1.lighter)
			p.fill(Main1.blendColor(p.color(255),p.color(color), Main1.SUBTRACT));
		else p.fill(color);
		((Main1) p).roundRect( innerRadius1 - 275 - 65, 60 - 20, 130, 40);
		p.fill(0);
		p.textFont(font18);
		p.text("More Groups", innerRadius1 - 275 ,  60 + 8);
		color = p.color(0,255,0,200);;
		if(Main1.lighter)
			p.fill(Main1.blendColor(p.color(255),p.color(color), Main1.SUBTRACT));
		else p.fill(color);
		((Main1) p).roundRect( innerRadius1 - 275 - 65, 110 - 20, 130, 40);
		p.fill(0);
		p.textFont(font18);
		p.text("Fewer Groups", innerRadius1 - 275 ,  110 + 8);
		if((newAnnotationGroup.type.equals("Raw")))
		{
			p.text("Data Distribution:", innerRadius1 - 275, 200 +8);
			if(!percentValues) p.fill(255,255,0);
			else p.fill(255,255,0,100);
			p.rect(innerRadius1 - 275 - 100, 235 - 20, 200, 40);
			p.fill(0);
			p.text("Raw Value", innerRadius1 - 275, 235 +8);
			if(percentValues) p.fill(255,255,0);
			else p.fill(255,255,0,100);
			p.rect(innerRadius1 - 275 - 100, 275 - 20, 200, 40);
			p.fill(0);
			p.text("% of Total Expression", innerRadius1 - 275, 275 +8);
		}
		
	
		
		if(true) p.fill(240,237,167);
		else p.fill(255,255,0);
		((Main1) p).roundRect( -innerRadius1 + 350 - 50, innerRadius1 - 200 + 20, 100, 40);
		p.fill(0);
		p.textFont(font18);
		p.text("Create", -innerRadius1 + 350 ,  innerRadius1 - 200 + 48);
		p.fill(227,81,23);
		((Main1) p).roundRect( innerRadius1 - 350 - 50, innerRadius1 - 200 + 20, 100, 40);
		p.fill(0);
		p.text("Cancel", innerRadius1 - 350,  innerRadius1 - 200 + 48);
		p.scale(WIDTH1/p.width, HEIGHT1/p.height);
	}
	public void booleanGroupPopup(PApplet p)
	{
		p.scale(p.width/WIDTH1,p.height/HEIGHT1);
		p.fill(255,255,255,200);
		p.noStroke();
		p.rectMode(Main1.CORNER);
		((Main1) p).roundRect(bool1.x1 - 420,bool1.y1 - 320, 400, 300);
		p.textFont(font32);
		p.textAlign(Main1.CENTER);
		p.fill(48,165,252);
		p.text("New Boolean Group?", bool1.x1 - 220,  bool1.y1 - 290);
		p.textFont(font14);
		p.fill(0);
		p.text("Show lines to genes that", bool1.x1 - 220,  bool1.y1 - 260);
		if(!b1) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -420, bool1.y1  - 240, 80, 30);
		if(!b2) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -330, bool1.y1  - 240, 95, 30);
		if(bool1.type.equals("Raw"))
		{
			if(!b7) p.fill(190);
			else p.fill(100);
			p.rect(bool1.x1 -225, bool1.y1  - 242, 30, 15);
			if(!b8) p.fill(190);
			else p.fill(100);
			p.rect(bool1.x1 -225, bool1.y1  - 224, 30, 15);
			p.fill(0);
			p.text("Are", bool1.x1 -380, bool1.y1  - 218);
			p.text("Are not", bool1.x1 -283, bool1.y1  - 218);
			p.text("+", bool1.x1 -210, bool1.y1  - 231);
			p.text("-", bool1.x1 -210, bool1.y1  - 213);
			p.textAlign(Main1.LEFT);
			p.text("expressed in "+ bool1.name, bool1.x1 - 190, bool1.y1 - 218);
		}
		else
		{
			p.fill(0);
			p.text("Bind", bool1.x1 -380, bool1.y1  - 218);
			p.text("Do not Bind", bool1.x1 -283, bool1.y1  - 218);
			p.textAlign(Main1.LEFT);
			p.text("to "+ bool1.name, bool1.x1 - 230, bool1.y1 - 218);
		}
		p.textAlign(Main1.CENTER);
		if(!b3) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -310, bool1.y1  - 200, 80, 30);
		if(!b4) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -210, bool1.y1  - 200, 80, 30);
		p.fill(0);
		p.text("AND", bool1.x1 -270, bool1.y1  - 178);
		p.text("OR", bool1.x1 -170, bool1.y1  - 178);
		
		if(!b5) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -420, bool1.y1  - 160, 80, 30);
		if(!b6) p.fill(190);
		else p.fill(100);
		p.rect(bool1.x1 -330, bool1.y1  - 160, 95, 30);
		if(bool2.type.equals("Raw"))
		{
			if(!b9) p.fill(190);
			else p.fill(100);
			p.rect(bool1.x1 -225, bool1.y1  - 162, 30, 15);
			if(!b10) p.fill(190);
			else p.fill(100);
			p.rect(bool1.x1 -225, bool1.y1  - 144, 30, 15);
			p.fill(0);
			p.text("Are", bool1.x1 -380, bool1.y1  - 138);
			p.text("Are not", bool1.x1 -283, bool1.y1  - 138);
			p.text("+", bool1.x1 -210, bool1.y1  - 151);
			p.text("-", bool1.x1 -210, bool1.y1  - 133);
			p.textAlign(LEFT);
			p.text("expressed in "+ bool2.name, bool1.x1 - 190, bool1.y1 - 138);
		}
		else
		{
			p.fill(0);
			p.text("Bind", bool1.x1 -380, bool1.y1  - 138);
			p.text("Do not Bind", bool1.x1 -283, bool1.y1  - 138);
			p.textAlign(LEFT);
			p.text("to "+ bool2.name, bool1.x1 - 230, bool1.y1 - 138);
		}
		p.textAlign(CENTER);
		if(b1==b2 || b3==b4 || b5==b6) p.fill(240,237,167);
		else p.fill(255,255,0);
		((Main1) p).roundRect( bool1.x1 -370, bool1.y1 - 75, 100, 40);
		p.fill(0);
		p.textFont(font18);
		p.text("Create", bool1.x1 - 320,  bool1.y1 - 50);
		p.fill(227,81,23);
		((Main1) p).roundRect( bool1.x1 -170, bool1.y1 - 75, 100, 40);
		p.fill(0);
		p.text("Cancel", bool1.x1 - 120,  bool1.y1 - 50);
		p.scale(WIDTH1/p.width, HEIGHT1/p.height);
		
	}
	public void showAnnotationPopup(Annotations a, PApplet p)
	{
		//p.scale(p.width/WIDTH1,p.height/HEIGHT1);
		p.scale(WIDTH1/p.width, HEIGHT1/p.height);
		p.textFont(font14);
		p.fill(0,128,255);
		p.rectMode(Main1.CORNER);
		p.fill(0,0,0,100);
		p.rect(a.labelX + 40, a.labelY - 40, 250, 80);
		p.fill(255,255,255);
		p.text(a.parentType + "\t" + a.groupName, a.labelX + 40 + 5, a.labelY - 40 + 15);
		
		int count = 0;
		int groupNum = -1;
		if(!a.parentAnnotations.parentType.equals("All")) 
		{
			for(int k = 0; k< annotationOrder.length; k++)
				if(a.parentType.equals(annotationOrder[k]))
					groupNum = k;
			if(groupNum >= 0)
			{
				for(Gene gene: firstAnnotation.genes)
					if (gene.annotations.get(Main1.annotationColumn[groupNum]).equals(a.groupName)) 
					{
						count++;
					}			
				if(a.parentAnnotations.genes.length !=firstAnnotation.genes.length)
				{
					Hypergeometric h = new Hypergeometric(a.parentAnnotations.genes.length, firstAnnotation.genes.length,count);
					NumberFormat formatter = new DecimalFormat("0.#E0##");
					double temp = 0;
					for (int i = a.genes.length; i< (int)Math.min(h.getSampleSize(), h.getMarkedItemsCount()); i++)
						temp = temp + h.pdf(i);
					p.text(a.genes.length + " Genes in Section (" + Math.round(((float)a.genes.length/firstAnnotation.genes.length)*100) + "% of Total, p = " + formatter.format(temp) + ")", a.labelX + 40 + 5, a.labelY - 40 + 60);
				}
			}
		}
		
		p.text(Math.round(a.percentParentExpression*100) + "% " + "of " + a.parentAnnotations.parentType + "-" + a.parentAnnotations.groupName+ " Expression", a.labelX + 40 + 5, a.labelY - 40 + 30);
		p.text(Math.round(a.groupTotalExpression/firstAnnotation.groupTotalExpression*100) + "% " + "of " + "Total Expression", a.labelX + 40 + 5, a.labelY - 40 + 45);
		if (groupNum == -1) 
			p.text(a.genes.length + " Genes in Section (" + Math.round(((float)a.genes.length/firstAnnotation.genes.length)*100) + "% of Total )", a.labelX + 40 + 5, a.labelY - 40 + 60);
		p.fill(150,150,255);
		p.textFont(font12);
		p.text("Show/Hide Genes", a.labelX + 40 + 5, a.labelY - 40 + 75);
		if(a.level > a.myLevels)
			p.text("Divide Annotation", a.labelX + 170 + 5, a.labelY - 40 + 75);
		else
			p.text("Collapse Annotation", a.labelX + 170 + 5, a.labelY - 40 + 75);
		p.fill(255,255,255);
		p.textFont(font15);
		p.text("X", a.labelX + 40 + 235, a.labelY - 40 + 13);
		p.stroke(255);
		p.line(a.labelX, a.labelY, a.labelX + 40, a.labelY - 40);
		p.rectMode(Main1.CENTER);
		//p.scale(WIDTH1/p.width, HEIGHT1/p.height);
	}

}
